]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
st/adjustment: Ensure changed signal emission is compressed
authorJulian Sparber <julian@sparber.net>
Tue, 21 Nov 2023 10:20:06 +0000 (11:20 +0100)
committerJulian Sparber <julian@sparber.net>
Tue, 21 Nov 2023 15:31:56 +0000 (16:31 +0100)
The docs say that `st_adjustment_set_values()` emits the `changed`
signal only once but it's actually emitted for each changed property,
this uses the `dispatch_properties_changed` vfunc to emit the `changed`
signal only per call to `st_adjustment_set_values()`. As a positive
side effect this also makes it possible to use `g_object_freeze/thaw_notify`
to compress the `changed` signal emission when using the setters for
properties.

This also fixes the wrong emission of the `changed` signal in
`st_adjustment_set_values()` when only the `value` property is changed.

Side note: the code is heavily inspired by GtkAdjustment

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/3023>

src/st/st-adjustment.c

index d2baa660ee3e2d782d030eb1e7691ca5f89117f7..2cf5f9260de42d5bce0f44abe550add7f8bd42a7 100644 (file)
@@ -282,6 +282,34 @@ st_adjustment_dispose (GObject *object)
   G_OBJECT_CLASS (st_adjustment_parent_class)->dispose (object);
 }
 
+static void
+st_adjustment_dispatch_properties_changed (GObject     *object,
+                                           guint        n_pspecs,
+                                           GParamSpec **pspecs)
+{
+  gboolean changed = FALSE;
+  gint i;
+
+  G_OBJECT_CLASS (st_adjustment_parent_class)->dispatch_properties_changed (object, n_pspecs, pspecs);
+
+  for (i = 0; i < n_pspecs; i++)
+    switch (pspecs[i]->param_id)
+      {
+      case PROP_LOWER:
+      case PROP_UPPER:
+      case PROP_STEP_INC:
+      case PROP_PAGE_INC:
+      case PROP_PAGE_SIZE:
+        changed = TRUE;
+        break;
+      default:
+        break;
+      }
+
+  if (changed)
+    g_signal_emit (object, signals[CHANGED], 0);
+}
+
 static void
 st_adjustment_class_init (StAdjustmentClass *klass)
 {
@@ -291,6 +319,7 @@ st_adjustment_class_init (StAdjustmentClass *klass)
   object_class->get_property = st_adjustment_get_property;
   object_class->set_property = st_adjustment_set_property;
   object_class->dispose = st_adjustment_dispose;
+  object_class->dispatch_properties_changed = st_adjustment_dispatch_properties_changed;
 
   /**
    * StAdjustment:actor:
@@ -544,11 +573,11 @@ st_adjustment_clamp_page (StAdjustment *adjustment,
  * When setting multiple adjustment properties via their individual
  * setters, multiple #GObject::notify and #StAdjustment::changed
  * signals will be emitted. However, it’s possible to compress the
- * #GObject::notify signals into one by calling
- * g_object_freeze_notify() and g_object_thaw_notify() around the
+ * #GObject::notify and #StAdjustment::changed signals into one of each
+ * by calling g_object_freeze_notify() and g_object_thaw_notify() around the
  * calls to the individual setters.
  *
- * Alternatively, using st_adjustment_set_values() will compress both
+ * Alternatively, st_adjustment_set_values() can be used to compress
  * #GObject::notify and #StAdjustment::changed emissions.
  */
 static gboolean
@@ -561,8 +590,6 @@ st_adjustment_set_lower (StAdjustment *adjustment,
     {
       priv->lower = lower;
 
-      g_signal_emit (adjustment, signals[CHANGED], 0);
-
       g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_LOWER]);
 
       /* Defer clamp until after construction. */
@@ -600,8 +627,6 @@ st_adjustment_set_upper (StAdjustment *adjustment,
     {
       priv->upper = upper;
 
-      g_signal_emit (adjustment, signals[CHANGED], 0);
-
       g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_UPPER]);
 
       /* Defer clamp until after construction. */
@@ -636,8 +661,6 @@ st_adjustment_set_step_increment (StAdjustment *adjustment,
     {
       priv->step_increment = step;
 
-      g_signal_emit (adjustment, signals[CHANGED], 0);
-
       g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_STEP_INC]);
 
       return TRUE;
@@ -668,8 +691,6 @@ st_adjustment_set_page_increment (StAdjustment *adjustment,
     {
       priv->page_increment = page;
 
-      g_signal_emit (adjustment, signals[CHANGED], 0);
-
       g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_PAGE_INC]);
 
       return TRUE;
@@ -700,8 +721,6 @@ st_adjustment_set_page_size (StAdjustment *adjustment,
     {
       priv->page_size = size;
 
-      g_signal_emit (adjustment, signals[CHANGED], 0);
-
       g_object_notify_by_pspec (G_OBJECT (adjustment), props[PROP_PAGE_SIZE]);
 
       /* We'll explicitly clamp after construction. */
@@ -728,8 +747,8 @@ st_adjustment_set_page_size (StAdjustment *adjustment,
  *
  * Use this function to avoid multiple emissions of the #GObject::notify and
  * #StAdjustment::changed signals. See st_adjustment_set_lower() for an
- * alternative way of compressing multiple emissions of #GObject::notify into
- * one.
+ * alternative way of compressing multiple emissions of #GObject::notify and
+ * #StAdjustmet::changed into one of each.
  */
 void
 st_adjustment_set_values (StAdjustment *adjustment,
@@ -740,34 +759,19 @@ st_adjustment_set_values (StAdjustment *adjustment,
                           gdouble       page_increment,
                           gdouble       page_size)
 {
-  StAdjustmentPrivate *priv;
-  gboolean emit_changed = FALSE;
-
   g_return_if_fail (ST_IS_ADJUSTMENT (adjustment));
   g_return_if_fail (page_size >= 0 && page_size <= G_MAXDOUBLE);
   g_return_if_fail (step_increment >= 0 && step_increment <= G_MAXDOUBLE);
   g_return_if_fail (page_increment >= 0 && page_increment <= G_MAXDOUBLE);
 
-  priv = st_adjustment_get_instance_private (adjustment);
-
-  emit_changed = FALSE;
-
   g_object_freeze_notify (G_OBJECT (adjustment));
 
-  emit_changed |= st_adjustment_set_lower (adjustment, lower);
-  emit_changed |= st_adjustment_set_upper (adjustment, upper);
-  emit_changed |= st_adjustment_set_step_increment (adjustment, step_increment);
-  emit_changed |= st_adjustment_set_page_increment (adjustment, page_increment);
-  emit_changed |= st_adjustment_set_page_size (adjustment, page_size);
-
-  if (value != priv->value)
-    {
-      st_adjustment_set_value (adjustment, value);
-      emit_changed = TRUE;
-    }
-
-  if (emit_changed)
-    g_signal_emit (G_OBJECT (adjustment), signals[CHANGED], 0);
+  st_adjustment_set_lower (adjustment, lower);
+  st_adjustment_set_upper (adjustment, upper);
+  st_adjustment_set_step_increment (adjustment, step_increment);
+  st_adjustment_set_page_increment (adjustment, page_increment);
+  st_adjustment_set_page_size (adjustment, page_size);
+  st_adjustment_set_value (adjustment, value);
 
   g_object_thaw_notify (G_OBJECT (adjustment));
 }